package com.yingdong.centerserver.opcode;

import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;

import com.yingdong.centerserver.inner.handler.CenterServerHandler;
import com.yingdong.centerserver.inner.handler.UserLoginHandler;
import com.yingdong.centerserver.inner.message.GameMessage;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;

public class Dispatcher {
	private static final int TABLE_MAX_SIZE = 10000;
	private static final int QUEUE_SIZE = 10000;
	public static Map<Integer, Channel> centerServerSessionMap = new ConcurrentHashMap<>();
	public static Map<Integer, Integer> userIdMap = new ConcurrentHashMap<>();
	public static CenterServerHandler[] handlerTable = new CenterServerHandler[TABLE_MAX_SIZE];
	public static BlockingQueue<GameMessage> receiveBuffers = new LinkedBlockingQueue<GameMessage>(QUEUE_SIZE);

	public static void init() {
		initTable();
		initThread();
	}

	public static void initTable() {
		handlerTable[InternalOpcode.SCENESERVER_REGIST] = new UserLoginHandler();
	}

	public static void initThread() {
		Thread receiveThread = new Thread(new Runnable() {
			public void run() {
				while (true) {
					ByteBuf buffer = null;
					try {
						GameMessage msg = receiveBuffers.take();
						buffer = msg.getBuffer();

						int allength = buffer.readInt();
						int length = buffer.readInt();
						int opcode = buffer.readInt();
						buffer.readerIndex(length);
						ByteBuf buffer2 = null;
						while (buffer.isReadable()) {
							int session = buffer.readInt();
							if (session == 0) {
								for (Channel channel : centerServerSessionMap.values()) {
									if (channel != null) {
										buffer2 = buffer.slice(4, length);
										buffer2.writeInt(session);
										channel.writeAndFlush(buffer2);
										buffer.retain();
									}
								}
								break;
							}
							buffer2 = buffer.slice(4, length);
							if (handlerTable[opcode] != null) {
								GameMessage message = new GameMessage(buffer2, opcode, session, msg.getChannel());
								handlerTable[opcode].handle(session, message);
							
							} else {
								Channel channel = centerServerSessionMap.get(session);
								if (channel != null) {
									buffer2.writeInt(session);
									channel.writeAndFlush(buffer2);
									buffer.retain();
								}

							}

						}
						buffer.release();
					} catch (Exception e) {

					} finally {
						buffer.release();
					}
				}
			}
		});
		receiveThread.setName("ReceiveThread");
		receiveThread.start();

	}

}
